#include <QApplication>
#include <iostream>
#include <string>
#include <map>
#include "CustomService.h"
#include "ServiceHandle.h"


enum ServiceCmdType
{
    kServiceCmdTypeUnknown = -1,
    kServiceCmdTypeHelp,
    kServiceCmdTypeCommon,
    kServiceCmdTypeInstall,
    kServiceCmdTypeUninstall,
    kServiceCmdTypeStart,
    kServiceCmdTypeStop

};

std::map<std::string, ServiceCmdType> mapCmd
{
    { "help", kServiceCmdTypeHelp },
    { "common", kServiceCmdTypeCommon },
    { "install", kServiceCmdTypeInstall },
    { "uninstall", kServiceCmdTypeUninstall },
    { "start", kServiceCmdTypeStart },
    { "stop", kServiceCmdTypeStop }

};

void Usage()
{
    std::cout << "Usage: QtService [command] [option1] [option2]\n";
    std::cout << "command and options:\n";
    std::cout << "\tinstall [service name]:     install service, <service name> is optional, default is \"Custom Qt Server\" \n";
    std::cout << "\tstop [service name]:        stop service\n";
    std::cout << "\tstart [service name]:       start service\n";
    std::cout << "\tuninstall [service name]:   uninstall service\n";
    std::cout << "\tcommon:                     start process in common mode\n";
    std::cout << "\thelp:                       show usage\n";
}

bool CheckValidCmd(const std::string& strCmd, ServiceCmdType& nCmd)
{
    bool bValid = false;
    auto itFind = mapCmd.find(strCmd);
    if(itFind != mapCmd.end()) {
        bValid = true;
        nCmd = itFind->second;
    }

    return bValid;
}

// install/uninstall/start/stop service via inner action
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    if(argc > 1) {
        int nIndex = 0;
        std::string strCmd = argv[++nIndex];
        ServiceCmdType nCmdType = kServiceCmdTypeUnknown;
        if(!CheckValidCmd(strCmd, nCmdType) || kServiceCmdTypeHelp == nCmdType) {
            Usage();
            return 0;
        }
        if(kServiceCmdTypeCommon == nCmdType) {
            SERVER_CTRL_INST.start();
            auto nCode = a.exec();
            SERVER_CTRL_INST.stop();
            return nCode;
        }
        if(argc < 3) {
            Usage();
            return 0;
        }

        std::string strServiceName = argv[++nIndex];
        switch(nCmdType) {
        case kServiceCmdTypeInstall: {
            SERVER_CTRL_INST.InstallService(strServiceName);
            break;
        }
        case kServiceCmdTypeUninstall: {
            SERVER_CTRL_INST.UninstallService(strServiceName);
            break;
        }
        case kServiceCmdTypeStart: {
            SERVER_CTRL_INST.StartService(strServiceName);
            break;
        }
        case kServiceCmdTypeStop: {
            SERVER_CTRL_INST.StopService(strServiceName);
            break;
        }
        default:
            break;
        }
        return 0;
    }
    // start exe with service(default)
    CustomService service(argc, argv);
    auto nCode = service.exec();
    service.DoClean();
    return nCode;
}

